home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / QuickDraw / ClutWind / CLUTSample.a next >
Encoding:
Text File  |  1992-07-15  |  29.1 KB  |  836 lines  |  [TEXT/MPS ]

  1. *
  2. *    Apple Macintosh Developer Technical Support
  3. *
  4. *
  5. *    CLUTSample
  6. *
  7. *
  8. *       Loosely based in the sample SAMPLE this program shows
  9. *       how to create a window and display on it the colors of the CLUT
  10. *    associated with the device the window sits on top of.
  11. *
  12. *    Left to the curious reader are some improvements such as, remembering the
  13. *    positions of each open window, so if you use this program to monitor your
  14. *    color tables it will position the windows in the last place you opened them.
  15. *    The treatment of direct devices is kind of 'casual' a better color display may 
  16. *    be appropriate. Last, it may be desireable to change the size of the color
  17. *    rectangles depending on the depth of the color table.
  18.  
  19. *    Check Sample sources for more detailed documentation.
  20.  
  21. * ================================================
  22. * -------------- INCLUDES SECTION ----------------
  23. * ================================================
  24.     
  25.     PRINT    PUSH,OFF            ; don't print any of this stuff
  26.  
  27.     INCLUDE    'ToolEqu.a'
  28.     INCLUDE    'Traps.a'
  29.     INCLUDE    'PackMacs.a'
  30.     INCLUDE    'QuickEqu.a'
  31.     INCLUDE    'SysEqu.a'
  32.     INCLUDE    'CLUTSample.inc1.a'        ; all our macros and data templates
  33.  
  34.     PRINT    POP                ; restore the PRINT options
  35.     
  36.  
  37. * ================================================
  38. * ---------  DATA STORAGE ALLOCATION  ------------
  39. * ================================================
  40. * Global data storage.  All global memory is allocated here.  The
  41. * Linker will load all global data offset from A5, and the Asm knows this.
  42. * Therefore, no reference to (A5) is required in the code. Hooray!
  43. * Here we declare two data structures using our templates defined previously.
  44. * They must be EXPORTed here for other files that need to IMPORT them.
  45.  
  46.         EXPORT    (QD,G):DATA
  47.  
  48. QD        DS    MyQDGlobals        ; QuickDraw's globals
  49. G        DS    AppGlobals        ; application's globals
  50.  
  51.  
  52. * ================================================
  53. * ---------  INITIALIZATION PROC  ------------
  54. * ================================================
  55.         SEG     'Initialize'        ; case sensitive
  56. Initialize    PROC                ; Initialize everything
  57.  
  58. CountReg    EQU    D4            ; temporary registor to count loops
  59.  
  60. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  61. ParamBegin    EQU    *            ; start parameters after this point
  62. ParamSize    EQU    ParamBegin-*        ; size of all the passed parameters
  63. RetAddr     DS.L    1            ; place holder for return address
  64. A6Link        DS.L    1            ; place holder for A6 link
  65. CurMBar        DS.L    1            ; local handle to our menubar
  66. TheEvent     DS    EventRecord         ; local copy of the event record
  67. LocalSize    EQU     *            ; size of all the local variables
  68.         ENDR
  69.         
  70.         IMPORT    GoGetRect,AlertUser,SysEnvirons,    \
  71.             OpenClutWind, \
  72.             TrapAvailable        ; linked in with Interface.o
  73.  
  74.         WITH    StackFrame        ; cover our local stack frame
  75.         LINK    A6,#LocalSize        ; allocate our local stack frame
  76.         
  77.         MOVEM.L    CountReg,-(SP)         ; save the current registor values
  78.         MOVE.W    #False,G.InBackground    ; we start out in the foreground
  79.         MOVE.W    #True,G.Stopped        ; we'll start with the red light on
  80.  
  81. * ------------- INITIALIZE MANAGERS -------------
  82.  
  83. @1        PEA     QD.thePort         ; initialize all of the Managers
  84.         _InitGraf            ; please don't flush my events
  85.         _InitFonts
  86.         _InitWindows
  87.         _InitMenus
  88.         _TEInit
  89.         CLR.L    -(SP)    
  90.         _InitDialogs
  91.         _InitCursor
  92.         
  93. * Call MPPOpen and ATPLoad at this point to initialize AppleTalk, if you are using it.
  94. * NOTE -- It is no longer necessary, and actually unhealthy, to check PortBUse and
  95. * SPConfig before opening AppleTalk. The drivers are capable of checking for port
  96. * availability themselves.  This next bit of code is necessary to allow the default
  97. * button of our alert be outlined.
  98.      
  99. * ------------- WASTE THREE EVENTS -------------
  100.  
  101.         MOVE.W    #2,CountReg        ; set register value to loop 3 times
  102. Loop        CLR.W    -(SP)            ; space for result
  103.         MOVE.W    #EveryEvent,-(SP)    ; the events we want
  104.         PEA    TheEvent(A6)        ; pass a pointer to our event
  105.         _EventAvail
  106.         MOVE.W    (SP)+,D0        ; result code
  107.         DBF    CountReg,Loop        ; decrement count, if count < 0 then continue
  108.  
  109. * ------------- GET THE ENVIRONMENT -------------
  110.  
  111.         CLR.W    -(SP)            ; create space for result
  112.         MOVE.W    #EnvironsVersion,-(SP)    ; version of SysEnvirons we want
  113.         PEA    G.Mac            ; the global environment record
  114.         JSR    SysEnvirons        ; we can ignore any errors here,
  115.         MOVE.W    (SP)+,D0        ; SysEnvirons will fill in regardless
  116.         MOVE.W    G.Mac.MachineType,D0     ; negitive value means old ROMs
  117.         BPL.S    @2            ; 128k ROMs or better, continue on
  118.         JMP    AlertUser        ; we don't want to run on 64k ROMs
  119.  
  120. * ------------- TEST FOR WAITNEXTEVENT -------------
  121. * 1.02 - Move TrapAvailable call to after SysEnvirons so that
  122. * we can tell in TrapAvailable if a tool trap value is out of range.
  123.  
  124. @2        CLR.W    -(SP)            ; space for result of trap test
  125.         MOVE.W    #WaitNextEvent,-(SP)    ; pass the trap number of WaitNextEvent trap
  126.         BSR    TrapAvailable        ; test for this trap
  127.         MOVE.W    (SP)+,G.HasWNEvent    ; put the result in our global flag
  128.             
  129.  
  130.         MOVE.L    applLimit,D1        ; get pointer to ApplLimit
  131.         MOVE.L    applZone,D0        ; get pointer to ApplicZone
  132.         SUB.L    D0,D1            ; subtract the ApplicZone from ApplLimit
  133.         CMPI.L    #MinHeap,D1        ; do we have enough memory?
  134.         BPL.S    @3            ; yes we do, continue on
  135.         JMP    AlertUser        ; no, report the error
  136.         
  137. @3        _PurgeSpace            ; results will be in A0 and D0
  138.         CMPI.L    #MinSpace,D0        ; do we have enough purgeable space?
  139.         BPL.S    @4
  140.         JMP    AlertUser        ; no, report the error
  141.  
  142. * ------------- SET UP THE MENUS -------------
  143.     
  144. @4        CLR.L    -(SP)            ; space for MenuBar handle
  145.         MOVE.W    #rMenuBar,-(SP)        ; our MenuBar resource
  146.         _GetNewMBar            ; the modern way, get a MenuBar
  147.         MOVE.L    (SP),CurMBar(A6)
  148.         _SetMenuBar
  149.         MOVEA.L    CurMBar(A6),A0        ; we're done with that handle
  150.         _DisposHandle            ; there is a result in D0
  151.         CLR.L    -(SP)
  152.         MOVE.W    #AppleMenu,-(SP)
  153.         _GetMHandle            ; put Apple menu handle on stack
  154.         MOVE.L    #'DRVR',-(SP)        ; get all the DAs
  155.         _AddResMenu
  156.         _DrawMenuBar
  157.  
  158. Exit        MOVEM.L    (SP)+,CountReg        ; restore the registors
  159.         UNLK    A6            ; destroy the link
  160.         MOVEA.L    (SP)+,A0        ; pull off the return address
  161.         ADDA.L    #ParamSize,SP        ; strip all of the caller's parameters
  162.         JMP    (A0)            ; return to the caller
  163.  
  164.         DbgInfo    Initialz        ; this name will appear in the debugger
  165.         ENDP
  166. * ================================================
  167. * PROCEDURE OpenClutWind();
  168. * ================================================
  169.         SEG    'Main'            ; case sensitive
  170. OpenClutWind    PROC
  171.  
  172. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  173. ParamBegin    EQU    *            ; passed parameter of the window pointer
  174. ParamSize    EQU    ParamBegin-*        ; size of all the passed parameters
  175. RetAddr     DS.L    1            ; place holder for return address
  176. A6Link        DS.L    1            ; place holder for A6 link
  177. LocalSize    EQU     *            ; size of all the local variables
  178.         ENDR
  179.         
  180.         IMPORT    DrawClut,NulMouse,OpenWindow
  181.         WITH    StackFrame,ClutWData    ; cover our local stack frame
  182.         LINK    A6,#LocalSize        ; allocate our local stack frame
  183.  
  184.         Clr.l    -(SP)
  185.         Move.W    #rWindow,-(SP)
  186.         Move.L    #ClutWDataSize,-(SP)
  187.         PEA    DrawClut
  188.         PEA    NulMouse
  189.         JSR    OpenWindow
  190.         MOVE.L    (SP)+,A0
  191. Exit
  192.         UNLK    A6            ; destroy the link
  193.         MOVEA.L    (SP)+,A0        ; pull off the return address
  194.         ADDA.L    #ParamSize,SP        ; strip all of the caller's parameters
  195.         JMP    (A0)            ; return to the caller
  196.  
  197.         DbgInfo    OpenClutWind
  198.         ENDP
  199.  
  200.  
  201.  
  202. * ================================================
  203. * PROCEDURE DoUpdate(window: WindowPtr);
  204. * ================================================
  205. * This is called when an update event is received for a window.
  206. * It calls DrawWindow to draw the contents of an application window.
  207. * As an efficiency measure that does not have to be followed, it
  208. * calls the drawing routine only if the visRgn is non-empty. This
  209. * will handle situations where calculations for drawing or drawing
  210. * itself is very time-consuming.
  211.  
  212.         SEG    'Main'            ; case sensitive
  213. DoUpdate    PROC
  214.  
  215. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  216. ParamBegin    EQU    *            ; start parameters after this point
  217. WindowPtr    DS.L    1            ; passed parameter of the window pointer
  218. ParamSize    EQU    ParamBegin-*        ; size of all the passed parameters
  219. RetAddr     DS.L    1            ; place holder for return address
  220. A6Link        DS.L    1            ; place holder for A6 link
  221. LocalSize    EQU     *            ; size of all the local variables
  222.         ENDR
  223.         
  224.         IMPORT    IsAppWindow,DrawWindow
  225.  
  226.         WITH    StackFrame        ; cover our local stack frame
  227.         LINK    A6,#LocalSize        ; allocate our local stack frame
  228.  
  229.         CLR.W    -(SP)            ; space for result of IsAppWindow
  230.         MOVE.L    WindowPtr(A6),-(SP)    ; pass the window pointer
  231.         BSR    IsAppWindow        ; test if this window was ours
  232.         MOVE.W    (SP)+,D0        
  233.         CMPI.W    #True,D0        ; it must be our window
  234.         BNE.S    Exit            ; it wasn't our window
  235.         
  236.         MOVE.L    WindowPtr(A6),-(SP)    ; update only the visible region
  237.         _BeginUpDate            ; region of the window
  238.         CLR.W    -(SP)            ; space for result
  239.         MOVEA.L    WindowPtr(A6),A0    ; the window pointer
  240.         MOVE.L    visRgn(A0),-(SP)    ; the window's visRgn handle
  241.         _EmptyRgn
  242.         MOVE.W    (SP)+,D0        ; result of EmptyRgn
  243.         CMPI.W    #True,D0        ; was the visRgn empty?
  244.         BEQ.S    @1            ; yes, then no update is needed
  245.         
  246.         Clr.l    -(SP)
  247.         MOVE.L    WindowPtr(A6),-(SP)
  248.         _GetWRefCon
  249.         Move.l    (SP)+,A2    ; Retrieve handle
  250.         Move.l    (A2),A0        ; Deref Handle
  251.         Move.l    (A0),A0        ; Get ProcPtr
  252.         MOVE.L    WindowPtr(A6),-(SP)
  253.         JSR    (A0)        ; draw the window
  254.         
  255. @1        MOVE.L    WindowPtr(A6),-(SP)    ; get pointer to window
  256.         _EndUpdate
  257.  
  258. Exit        UNLK    A6            ; destroy the link
  259.         MOVEA.L    (SP)+,A0        ; pull off the return address
  260.         ADDA.L    #ParamSize,SP        ; strip all of the caller's parameters
  261.         JMP    (A0)            ; return to the caller
  262.  
  263.         DbgInfo    DoUpdate        ; this name will appear in the debugger
  264.         ENDP
  265.  
  266. * ================================================
  267. * PROCEDURE DoActivate(window: WindowPtr; becomingActive: BOOLEAN);
  268. * ================================================
  269. * In this sample there is no other processing necessary other than what
  270. * the Window Manager has already done for us.  This would be the place to
  271. * perform an activate on TextEdit records, controls, lists, update GrowIcon, etc.
  272.  
  273.         SEG    'Main'            ; case sensitive
  274. DoActivate    PROC
  275.  
  276. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  277. ParamBegin    EQU    *            ; start parameters after this point
  278. WindowPtr    DS.L    1            ; passed parameter of the window pointer
  279. Active        DS.W    1            ; modifiers from the event record
  280. ParamSize    EQU    ParamBegin-*        ; size of all the passed parameters
  281. RetAddr     DS.L    1            ; place holder for return address
  282. A6Link        DS.L    1            ; place holder for A6 link
  283. LocalSize    EQU     *            ; size of all the local variables
  284.         ENDR
  285.         
  286.         IMPORT    IsAppWindow
  287.  
  288.         WITH    StackFrame        ; cover our local stack frame
  289.         LINK    A6,#LocalSize        ; allocate our local stack frame
  290.  
  291.         CLR.W    -(SP)            ; space for result of IsAppWindow
  292.         MOVE.L    WindowPtr(A6),-(SP)    ; pass the window pointer
  293.         BSR    IsAppWindow        ; test if this window was ours
  294.         MOVE.W    (SP)+,D0        ; get the result
  295.         CMPI.W    #True,D0        ; it must be our window
  296.         BNE.S    Exit            ; it wasn't our window
  297.  
  298.         CMPI.W    #True,Active(A6)    ; was it an Activate?
  299.         BNE.S    DeActivate        ; no, perform a Deactivate
  300.         
  301. * do the activate event processing here, then "BRA.S   Exit"
  302.         
  303. DeActivate                    ; do the deactivate event
  304.  
  305. * do the deactivate event processing here, then fall through to Exit
  306.         
  307.  
  308. Exit        UNLK    A6            ; destroy the link
  309.         MOVEA.L    (SP)+,A0        ; pull off the return address
  310.         ADDA.L    #ParamSize,SP        ; strip all of the caller's parameters
  311.         JMP    (A0)            ; return to the caller
  312.  
  313.         DbgInfo    Activate        ; this name will appear in the debugger
  314.         ENDP
  315.                     
  316. * ================================================
  317. * PROCEDURE DoMenuCommand(menuResult: LONGINT);
  318. * ================================================
  319. * This is called when an item is chosen from the menu bar (after calling
  320. * MenuSelect or MenuKey). It performs the right operation for each command.
  321. * It is good to have both the result of MenuSelect and MenuKey go to
  322. * one routine like this to keep everything organized.
  323.  
  324.         SEG    'Main'            ; case sensitive
  325. DoMenuCommand    PROC
  326.  
  327. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  328. ParamBegin    EQU    *            ; start parameters after this point
  329. MenuItem    DS.W    1            ; result from _MenuKey or _MenuSelect
  330. MenuID        DS.W    1            ; caller passed a long word, ID + Item
  331. ParamSize    EQU    ParamBegin-*        ; size of all the passed parameters
  332. RetAddr     DS.L    1            ; place holder for return address
  333. A6Link        DS.L    1            ; place holder for A6 link
  334. Deskname    DS.B    256            ; local storage for Desk Accs name
  335. TempPort    DS.L    1            ; local storage for the current port
  336. LocalSize    EQU     *            ; size of all the local variables
  337.         ENDR
  338.         
  339.         IMPORT    SetLight,DoCloseWindow,Terminate
  340.  
  341.         WITH    StackFrame        ; cover our local stack frame
  342.         LINK    A6,#LocalSize        ; allocate our local stack frame
  343.  
  344.         MOVE.W    MenuID(A6),D0        ; a nifty Pascal case-like macro
  345.         CASE#.W    (D0,IF),            \
  346.             (AppleMenu,    DoAppleMenu),    \
  347.             (FileMenu,    DoFileMenu)
  348.                         ; add additional Menus would go here
  349.         BRA.W    Exit            ; otherwise we will exit this procedure
  350.  
  351. * ------------- THE APPLE MENU ROUTINES -------------
  352. DoAppleMenu
  353.         CMPI.W    #AboutItem,MenuItem(A6)    ; was it the about item?
  354.         BNE.S    @1            ; no, must be a Desk Acc
  355.  
  356.         CLR.W    -(SP)            ; show the About dialog
  357.         MOVE.W    #rAboutAlert,-(SP)    ; resource for alert dialog
  358.         CLR.L    -(SP)            ; no filter procedure used here
  359.         _Alert                ; read the resource and display it
  360.         MOVE.W    (SP)+,D0        ; I don't care which item is was
  361.         BRA.W    Exit            ; all done with with Apple menu
  362.  
  363. @1        PEA    TempPort(A6)        ; open a desk accessory
  364.         _GetPort            ; save the current port
  365.         CLR.L    -(SP)            ; space for result of GetMHandle
  366.         MOVE.W    #AppleMenu,-(SP)
  367.         _GetMHandle            ; put Apple menu on stack
  368.         MOVE.W    MenuItem(A6),-(SP)    ; and here's the MenuItem
  369.         PEA    DeskName(A6)        ; now tell me the DA's name
  370.         _GetItem
  371.         CLR.W    -(SP)            ; space for OpenDeskAcc result
  372.         PEA    DeskName(A6)
  373.         _OpenDeskAcc            ; open that puppy
  374.         MOVE.W    (SP)+,D0        ; result
  375.         MOVE.L    TempPort(A6),-(SP)    ; restore the port
  376.         _SetPort
  377.         BRA.S    Exit
  378.         
  379. * ------------- THE FILE MENU ROUTINES -------------
  380. DoFileMenu    
  381.         MOVE.W    MenuItem(A6),D0     ; test the MenuItem
  382.         Case#.W    (D0,IF),            \
  383.             (NewItem,    FileNew),    \
  384.             (CloseItem,    FileClose),    \
  385.             (QuitItem,    FileQuit)
  386.         BRA.S    Exit            ; add additional menus here
  387. FileNew:
  388.         BSR     OpenClutWind
  389.         BRA.S    Exit
  390. FileClose
  391.         CLR.L    -(SP)            ; bug fix, didn't clear space for result -JDR 2/27/89
  392.         _FrontWindow
  393.         BSR    DoCloseWindow        ; close the window 
  394.         BRA.S    Exit
  395.  
  396. FileQuit    BSR    Terminate        ; let's get out of here
  397.         
  398. Exit        CLR.W    -(SP)    
  399.         _HiLiteMenu            ; unhilite all Menus
  400.         UNLK    A6            ; destroy the link
  401.         MOVEA.L    (SP)+,A0        ; pull off the return address
  402.         ADDA.L    #ParamSize,SP        ; strip all of the caller's parameters
  403.         JMP    (A0)            ; return to the caller
  404.  
  405.         DbgInfo    DoMenuCm        ; this name will appear in the debugger
  406.         ENDP
  407.         
  408. * ================================================
  409. * PROCEDURE OpenWindow(WINDid:Integer,WDataSize:Long,UpdateRtn:ProcPtr,MouseRtn:ProcPtr):WindowPtr
  410. * ================================================
  411.         SEG    'Main'            ; case sensitive
  412. OpenWindow    PROC    EXPORT
  413.         
  414. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  415. Result1        DS.L    1
  416. ParamBegin    EQU    *            ; start parameters after this point
  417. rWindow        DS.W    1            ; Id of WIND resource to use
  418. WDataSize    DS.L    1            ; Size of window data record to allocate
  419. ProcPtr        DS.L    1            ; Pointer to update routine for this window
  420. MouseRtn    DS.L    1
  421. ParamSize    EQU    ParamBegin-*        ; size of all the passed parameters
  422. RetAddr     DS.L    1            ; place holder for return address
  423. A6Link        DS.L    1            ; place holder for A6 link
  424. * insert locals here
  425. TempWord    DS.W    1
  426. TempLong    DS.L    1
  427. LocalSize    EQU     *            ; size of all the local variables
  428.         ENDR
  429.         IMPORT    AlertUser
  430.  
  431.         WITH    StackFrame        ; cover our local stack frame
  432.         LINK    A6,#LocalSize        ; allocate our local stack frame
  433.         
  434.         MOVE.L    #windowSize,D0
  435.         _NewPtr ,Clear            ; create a pointer in A0 and clear memory
  436.         CMPA.L    #NIL,A0            ; check for NIL pointer (result in D0)
  437.         BNE.S    @1            ; must have been a valid pointer
  438.         Move.w    #25,-(SP)        ; Error #
  439.         Pea    #'OpenWindow1'        ; Routine Name
  440.         Pea    #'No Memory for Window Record'    ; Message
  441.         JMP    AlertUser        ; couldn't get memory, report error
  442. @1        CLR.L    -(SP)            ; create space for result
  443.         MOVE.W    rWindow(A6),-(SP)    ; out window resource definition
  444.         MOVE.L    A0,-(SP)        ; our window record storage
  445.         MOVE.L    #-1,-(SP)        ; make it on top
  446.         _GetNewCWindow            ; create the window
  447.         Move.l    (SP)+,Result1(A6)
  448.         
  449.         MOVE.L    WDataSize(A6),D0
  450.         _NewHandle ,Clear        ; create a pointer in A0 and clear memory
  451.         CMPA.L    #NIL,A0            ; check for NIL pointer (result in D0)
  452.         BNE.S    @2            ; must have been a valid pointer
  453.         Move.w    #25,-(SP)    ; Error #
  454.         Pea    #'OpenWindow2'    ; Routine Name
  455.         Pea    #'No Memory for Window Record'    ; Message
  456.         JMP    AlertUser        ; couldn't get memory, report error
  457. @2        Move.l    A0,-(SP)        ; Save address
  458.         Move.l    Result1(A6),-(SP)
  459.         Move.l    A0,-(SP)
  460.         _SetWRefCon
  461.         Move.l    (SP)+,A0        ; restore address
  462.         Move.l    (A0),A0
  463.     WITH    ClutWData
  464.         Move.l    ProcPtr(A6),UpdateRtn(A0)    ; Update routine
  465.         Move.l    MouseRtn(A6),MouseDnRtn(A0)    ; Mouse down routine
  466.     ENDWITH
  467. Exit        UNLK    A6            ; destroy the link
  468.         MOVEA.L    (SP)+,A0        ; pull off the return address
  469.         ADDA.L    #ParamSize,SP        ; strip all of the caller's parameters
  470.         JMP    (A0)            ; return to the caller
  471.  
  472.         DbgInfo    OpenWindow
  473.         ENDP
  474.                     
  475. * ================================================
  476. * PROCEDURE DoMouseDown(Event: EventRecord);
  477. * ================================================
  478. * Handle all of the MouseDown events.
  479.  
  480.         SEG    'Main'            ; case sensitive
  481. DoMouseDown    PROC
  482.  
  483. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  484. ParamBegin    EQU    *            ; start parameters after this point
  485. EventPtr     DS.L    1             ; pointer to current event
  486. ParamSize    EQU    ParamBegin-*        ; size of all the passed parameters
  487. RetAddr     DS.L    1            ; place holder for return address
  488. A6Link        DS.L    1            ; place holder for A6 link
  489. WindowPtr    DS.L    1            ; local Window pointer variable
  490. Where        DS.L    1            ; local variable where the click was
  491. NewGrowRect    DS    Rect            ; local rect variable for SizeWindow
  492. LocalSize    EQU     *            ; size of all the local variables
  493.         ENDR
  494.  
  495.         IMPORT    AdjustMenus,DoContentClick
  496.  
  497.         WITH    StackFrame        ; cover our local stack frame
  498.         LINK    A6,#LocalSize        ; allocate our local stack frame
  499.         
  500.         MOVEA.L    EventPtr(A6),A0        ; event record only needed by SystemClick
  501.         MOVE.L    evtMouse(A0),Where(A6)    ; make a local copy of the mouse location
  502.  
  503.         CLR.W    -(SP)            ; space for FindWindow result
  504.         MOVE.L    Where(A6),-(SP)        ; the mouse point
  505.         PEA    WindowPtr(A6)        ; a local variable
  506.         _FindWindow            ; put the result in a register
  507.         MOVE.W    (SP)+,D0        ; a nifty Pascal case-like macro
  508.         Case#.W    (D0,IF),            \
  509.             (InMenuBar,    MenuEvent),    \
  510.             (InSysWindow,    SystemEvent),    \
  511.             (InContent,    Content),    \
  512.             (InDrag,    Drag)
  513.                         ; add additional routines here
  514.         BRA.S    Exit            ; otherwise we will exit this procedure
  515.  
  516. * ------------- THE DESK ACCS EVENT -------------
  517. MenuEvent    
  518.         BSR.W    AdjustMenus
  519.         CLR.L    -(SP)            ; space for MenuSelect
  520.         MOVE.L    Where(A6),-(SP)        ; Mouse coordinates
  521.         _MenuSelect            ; pass MenuSelect's result
  522.         BSR    DoMenuCommand        ; go do the menu and return
  523.         BRA.S    Exit
  524.  
  525. * ------------- THE DESK ACCS EVENT -------------
  526. SystemEvent    
  527.         MOVE.L    EventPtr(A6),-(SP)    ; get EventRecord and WindowPtr
  528.         MOVE.L    WindowPtr(A6),-(SP)    ; pass the window pointer and...
  529.         _SystemClick            ; let the system handle it
  530.         BRA.S    Exit
  531.  
  532. * ------------- THE CONTENT EVENT -------------
  533. Content        
  534.         CLR.L    -(SP)            ; was our window in front?
  535.         _FrontWindow            ; get front window's pointer
  536.         MOVE.L    (SP)+,D0
  537.         CMP.L    WindowPtr(A6),D0    ; was it in the front window?
  538.         BNE.S    @1            ; no, then just select window
  539.         
  540.         Clr.l    -(SP)
  541.         MOVE.L    WindowPtr(A6),-(SP)
  542.         _GetWRefCon
  543.         Move.l    (SP)+,A2        ; Retrieve handle
  544.         Move.l    (A2),A0            ; Deref Handle
  545.     WITH    ClutWData
  546.         Move.l    MouseDnRtn(A0),A0    ; Get ProcPtr
  547.     ENDWITH
  548.         MOVE.L    WindowPtr(A6),-(SP)    ; pass the window pointer
  549.         MOVE.L    EventPtr(A6),-(SP)    ; pass a pointer to the event
  550.         JSR    (A0)
  551.         BRA.S    Exit
  552.         
  553. @1        MOVE.L    WindowPtr(A6),-(SP)    ; only select this window
  554.         _SelectWindow            ; and take no further action
  555.         BRA.S    Exit
  556.  
  557. * ------------- THE DRAG A WINDOW EVENT -------------
  558. Drag        
  559.         MOVE.L    WindowPtr(A6),-(SP)    ; pass Window Pointer
  560.         MOVE.L    Where(A6),-(SP)        ; Mouse coordinates and boundary
  561.         PEA    QD.Screenbits.bounds    
  562.         _DragWindow            ; drag it the screen's boundary
  563.  
  564. Exit        
  565.         UNLK    A6            ; destroy the link
  566.         MOVEA.L    (SP)+,A0        ; pull off the return address
  567.         ADDA.L    #ParamSize,SP        ; strip all of the caller's parameters
  568.         JMP    (A0)            ; return to the caller
  569.  
  570.         DbgInfo    MouseDwn        ; this name will appear in the debugger
  571.         ENDP
  572.         
  573.         
  574. * ================================================
  575. * PROCEDURE DoEvent(event: EventRecord);
  576. * ================================================
  577. * Do the right thing for an event. Determine what kind of event it is,
  578. * and call the appropriate routines.
  579.  
  580.         SEG    'Main'            ; case sensitive
  581. DoEvent        PROC
  582.  
  583. ModifyReg    EQU    D4            ; we'll use this register locally
  584.  
  585. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  586. ParamBegin    EQU    *            ; start listing parameters here
  587. EventPtr     DS.L    1             ; pointer to current event
  588. ParamSize    EQU    ParamBegin-*        ; size of all the passed parameters
  589. RetAddr     DS.L    1            ; place holder for return address
  590. A6Link        DS.L    1            ; place holder for A6 link
  591. TheEvent     DS    EventRecord         ; local copy of the event record
  592. LocalSize    EQU     *            ; size of all the local variables
  593.         ENDR
  594.  
  595.         IMPORT    DoMouseDown,DrawWindow,    \
  596.             AdjustMenus,IsAppWindow,\
  597.             DoUpdate,DoActivate
  598.         
  599.         WITH    StackFrame,TheEvent    ; cover our local stack frame
  600.         LINK    A6,#LocalSize        ; allocate our local stack frame
  601.         MOVEM.L    ModifyReg,-(SP)        ; save this register before using it
  602.  
  603.         MOVEA.L    EventPtr(A6),A0        ; pointer of event passed by caller
  604.         LEA    TheEvent(A6),A1        ; pointer to local variable TheEvent
  605.         MOVE.L    #evtBlkSize,D0        ; size of an event record
  606.         _BlockMove            ; we now have a local copy of the event
  607.  
  608.         MOVE.W    Modify(A6),ModifyReg    ; a nifty Pascal case-like macro
  609.         MOVE.W    What(A6),D0        ; get the event number
  610.         Case#    (D0,Exit),    \    ; if not an event we support, then exit
  611.             ,        \    ;  0 Null (not used)
  612.             MouseDown,    \    ;  1 Mouse down
  613.             ,        \    ;  2 Mouse up (not used)
  614.             KeyDown,    \    ;  3 Key down
  615.             ,        \    ;  4 Key up (not used)
  616.             KeyDown,    \    ;  5 Auto key
  617.             Update,     \    ;  6 Update
  618.             Disk,        \    ;  7 Disk inserted
  619.             Activate,    \    ;  8 Activate/Deactivate
  620.             ,        \    ;  9 (not used)
  621.             ,        \    ; 10 Network (not used)
  622.             ,        \    ; 11 I/O Driver (not used)
  623.             ,        \    ; 12 App1 (not used)
  624.             ,        \    ; 13 App2 (not used)
  625.             ,        \    ; 14 App3 (not used)
  626.             OSEvent,        ; 15 OS Event or Suspend/Resume
  627.  
  628.  
  629. * ------------- THE MOUSEDOWN EVENT -------------
  630. MouseDown    
  631.         PEA    TheEvent(A6)        ; pass Event pointer in case of SystemClick
  632.         BSR    DoMouseDown
  633.         BRA    Exit
  634.  
  635. * ------------- THE KEYDOWN EVENT -------------
  636. KeyDown        
  637.         BTST    #CmdKey,ModifyReg    ; command key?
  638.         BEQ    Exit            ; no, then we're done
  639.         BSR.W    AdjustMenus        ; first, adjust the menus
  640.         CLR.L    -(SP)            ; space for MenuKey
  641.         MOVE.W    2+Message(A6),-(SP)    ; get the character
  642.         _MenuKey            ; is it a command?
  643.         BSR    DoMenuCommand        ; handle the command and return
  644.         BRA.S    Exit
  645.  
  646. * ------------- THE UPDATE EVENT -------------
  647. Update    
  648.         MOVE.L    Message(A6),-(SP)    ; pass the window pointer
  649.         BSR    DoUpdate        ; do the update
  650.         BRA.S    Exit
  651.  
  652. * ------------- THE DISK EVENT -------------
  653. Disk    
  654.         TST.W    Message(A6)        ; check for error
  655.         BEQ.S    @1            ; if none, skip
  656.         CLR.W    -(SP)
  657.         MOVE.L    #DITopLeft,-(SP)
  658.         MOVE.L    Message(A6),-(SP)
  659.         MOVE.W    #diBadMount,-(SP)
  660.         _Pack2                ; go through disk init package
  661.         ADDQ    #2,SP            ; throw away result
  662. @1        BRA.S    Exit
  663.  
  664. * ------------- THE ACTIVATE/DEACTIVATE EVENT -------------
  665. Activate    
  666.         BTST    #ActiveFlag,ModifyReg    ; was it an Activate?
  667.         BEQ.S    @1            ; no, perform a Deactivate
  668.  
  669.         MOVE.L    Message(A6),-(SP)    ; pass the current window pointer
  670.         MOVE.W    #True,-(SP)        ; set up for an Activate event
  671.         BSR    DoActivate        ; do the activate routine
  672.         BRA.S    Exit            ; we're done
  673.  
  674. @1        MOVE.L    Message(A6),-(SP)    ; pass current window pointer
  675.         MOVE.W    #False,-(SP)        ; set up for an Deactivate event
  676.         BSR    DoActivate        ; go do the activate routine
  677.         BRA.S    Exit            ; we're done
  678.  
  679. * ------------- THE SUSPEND/RESUME EVENT -------------
  680. * OSEvent is the event number of the suspend/resume and mouse-moved events sent
  681. * by MultiFinder. Once we determine that an event is an osEvent, we look at the
  682. * high byte of the message sent to determine which kind it is. To differentiate
  683. * suspend and resume events we check the resumeMask bit.
  684.  
  685. OSEvent        MOVE.B    Message(A6),D1        ; get high byte of Message in reg
  686.         CMPI.B    #SuspendResume,D1    ; test for message event type
  687.         BNE.S    Exit            ; not a suspend/resume event
  688.  
  689.         BTST    #0,3+Message(A6)    ; test bit zero in low byte of Message
  690.         BNE.S    @1            ; this is a resume event
  691.         
  692.         MOVE.W    #True,G.InBackground    ; a suspend event
  693.         CLR.L    -(SP)            ; bug fix, was passing Message to DoActivate -JDR 2/27/89 
  694.         _FrontWindow            ; pass the front window to DoActivate -JDR 2/27/89
  695.         MOVE.W    #False,-(SP)        ; pass false to cause deactivate
  696.         BSR    DoActivate        ; go do the activate routine
  697.         BRA.S    Exit
  698.  
  699. @1        MOVE.W    #False,G.InBackground    ; a resume event
  700.         CLR.L    -(SP)            ; bug fix, was passing Message to DoActivate -JDR 2/27/89 
  701.         _FrontWindow            ; pass the front window to DoActivate -JDR 2/27/89
  702.         MOVE.W    #True,-(SP)        ; pass false to cause activate
  703.         BSR    DoActivate        ; go do the activate routine
  704.         
  705. Exit        
  706.         MOVEM.L    (SP)+,ModifyReg        ; restore this register after use
  707.         UNLK    A6
  708.         MOVEA.L    (SP)+,A0        ; save the caller's address
  709.         ADDA.L    #ParamSize,SP        ; strip the caller's parameters
  710.         JMP    (A0)
  711.  
  712.         DbgInfo    DoEvent            ; this name will appear in the debugger
  713.         ENDP
  714.         
  715. * ================================================
  716. * PROCEDURE EventLoop;
  717. * ================================================
  718. * Get the events by calling WaitNextEvent, if it's available, otherwise
  719. * by calling GetNextEvent. Also call AdjustCursor before doing the event.
  720. * After returning from handling the event, we have to make sure the cursor
  721. * is still adjusted proper ONLY because this application can "sleep" forever.
  722.  
  723. * An event record is allocated on the stack.  A pointer to this event is
  724. * passed to "DoEvent".  We loop until the user has selects "Quit" in the
  725. * file menu.  This program will exit through the DoMenuCommand routine.
  726.  
  727. * 1.02 made adjustments to the event loop logic.  There was a bug in calling
  728. * AdjustCursor at the wrong time. (it crashed under _GetNextEvent too!)
  729.  
  730. * If you are using modeless dialogs that have editText items,
  731. * you will want to call IsDialogEvent to give the caret a chance
  732. * to blink, even if WNE/GNE returned FALSE. However, check FrontWindow
  733. * for a non-NIL value before calling IsDialogEvent.
  734.  
  735.         SEG    'Main'            ; case sensitive
  736. EventLoop    PROC                ; any source file can use this routine
  737.  
  738. StackFrame    RECORD    {A6Link},DECR        ; build a stack frame record
  739. ParamBegin    EQU    *            ; start listing parameters here
  740. ParamSize    EQU    ParamBegin-*        ; size of all the passed parameters
  741. RetAddr     DS.L    1            ; place holder for return address
  742. A6Link        DS.L    1            ; place holder for A6 link
  743. TheEvent     DS    EventRecord         ; local copy of the event record
  744. MouseMvdRgn    DS.L    1            ; local region for MouseMoved events
  745. MousePos    DS.L    1            ; local point for mouse position
  746. LocalSize    EQU     *            ; size of all the local variables
  747.         ENDR
  748.         
  749.         IMPORT    AdjustCursor,GetGlobalMouse
  750.  
  751.         WITH    StackFrame        ; cover our local stack frame
  752.         LINK    A6,#LocalSize        ; allocate our local stack frame
  753.         
  754.         CLR.L    -(SP)
  755.         _NewRgn                ; create region for AdjustCursor
  756.         MOVE.L    (SP)+,MouseMvdRgn(A6)    ; save the handle to this region
  757.  
  758. * ------------- GET NEXT EVENT LOOP -------------
  759. NextEvent    
  760.         CMPI.W    #True,G.HasWNEvent     ; see if we can call WaitNextEvent
  761.         BNE.S    @1            ; nope, old time events
  762.         
  763.         PEA    MousePos(A6)        ; here's the mouse
  764.         BSR    GetGlobalMouse        ; get global coordinate
  765.         MOVE.L    MousePos(A6),-(SP)    ; here's the mouse
  766.         MOVE.L    MouseMvdRgn(A6),-(SP)    ; the region to change
  767.         BSR    AdjustCursor        ; adjust the cursor and region
  768.         CLR.W    -(SP)            ; space for result
  769.         MOVE.W    #EveryEvent,-(SP)    ; the events we want
  770.         PEA    TheEvent(A6)        ; pointer to the event record
  771.         MOVE.L    #SleepValue,-(SP)    ; the sleeping time value
  772.         MOVE.L    MouseMvdRgn(A6),-(SP)    ; the current MouseRgn
  773.         _WaitNextEvent
  774.         BRA.S    @2            ; got an event to handle?
  775.     
  776.                         ; no WaitNextEvent trap available
  777. @1        _SystemTask            ; call SystemTask for drivers and DAs
  778.         CLR.W    -(SP)            ; space for result
  779.         MOVE.W    #EveryEvent,-(SP)    ; the events we want
  780.         PEA    TheEvent(A6)        ; pass a pointer to our event
  781.         _GetNextEvent
  782. @2        MOVE.W    (SP)+,D0        ; result code
  783.         BEQ.S    NextEvent        ; no event, get another one
  784.         
  785. GotEvent    MOVE.L    TheEvent.where(A6),-(SP); the mouse location
  786.         MOVE.L    MouseMvdRgn(A6),-(SP)    ; the region to change
  787.         BSR    AdjustCursor        ; adjust cursor BEFORE doing event
  788.         PEA    TheEvent(A6)        ; pass the pointer to our event
  789.         BSR    DoEvent            ; do the event and return
  790.  
  791.         BRA.S    NextEvent        ; done with that event, get the next
  792.  
  793. Exit        UNLK    A6            ; destroy the link
  794.         MOVEA.L    (SP)+,A0        ; pull off the return address
  795.         ADDA.L    #ParamSize,SP        ; strip all of the caller's parameters
  796.         JMP    (A0)            ; return to the caller
  797.  
  798.         DbgInfo    EvntLoop        ; this name will appear in the debugger
  799.         ENDP
  800.  
  801. * ================================================
  802. * --------------- MAIN ENTRY POINT ---------------
  803. * ================================================
  804. * This is the entry point of the program.  We start with data initializing
  805. * and then to get the System environment (SysEnvirons).  We unload the
  806. * initialization code segment and finally get started with the EventLoop.
  807.  
  808.         SEG    'Main'            ; case sensitive
  809. StartUp            MAIN                ; entry point of the program
  810.         
  811.         IMPORT    _DataInit,Initialize,    \
  812.             ForceEnvirons,EventLoop
  813.  
  814.         JSR    _DataInit        ; initialize those constants    
  815.         PEA    _DataInit        ; get rid of that segment
  816.         _UnloadSeg
  817.  
  818. * If you have stack requirements that differ from the default, then you could
  819. * use SetApplLimit to increase StackSpace at this point, before calling MaxApplZone.
  820.  
  821.         _MaxApplZone            ; result in D0
  822.         JSR    Initialize        ; get things the program set up
  823.         PEA    Initialize
  824.         _UnloadSeg            ; we're done this that segment too
  825.  
  826. * ------------- SET UP THE CLUT WINDOW -------------
  827.         BSR    OpenClutWind
  828.         
  829.  
  830.         LEA    EventLoop,A0        ; on your mark, get set,...
  831.         JMP    (A0)            ; go into the event loop
  832.         ENDP
  833.  
  834.         END                ; end of this source file
  835.  
  836.